<template>
    <el-dialog :title="title" :visible="dialogVisible" @close="cancelClick">
        <el-form ref="form" :model="form" :rules="rules" label-width="120px">
            <el-form-item label="部门名称" prop="name">
                <el-input v-model="form.name" placeholder="1-20个字符" style="width: 80%;"></el-input>
            </el-form-item>
            <el-form-item label="部门编码" prop="code">
                <el-input v-model="form.code" placeholder="1-20个字符" style="width: 80%;"></el-input>
            </el-form-item>
            <el-form-item label="部门负责人" prop="managerId">
                <el-select @focus="getManagerList" v-model="form.managerId" placeholder="请选择部门负责人" style="width: 80%;">
                    <el-option 
                        :label="manager.username" 
                        :value="manager.id" 
                        v-for="manager in managerList" 
                        :key="manager.id"
                        >
                    </el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="部门介绍" prop="introduce">
                <el-input type="textarea" :rows="3" v-model="form.introduce" placeholder="1-200个字符" style="width: 80%;" maxlength="200" show-word-limit></el-input>
            </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
            <el-button @click="cancelClick">取 消</el-button>
            <el-button type="primary" @click="confirmClick">确 定</el-button>
        </div>
    </el-dialog>
</template>

<script>
import { getDepartments, addDepartment, updDepartment } from '@/api/departments'
import { getEmployeesSimp } from '@/api/employees'

export default {
    name: 'AddDepartment',
    props: {
        // 弹层的标题
        title: {
            type: String,
            required: true
        },
        // 弹层的展示
        dialogVisible: {
            type: Boolean,
            required: true
        },
        // 当前部门
        department: {
            type: Object,
            required: true
        }
    },
    data() {
        // 校验同级部门下名称是否重复
        const checkNameRepeat = async (rule, value, callback) => {
            // getDepartments()不放在created函数里写是因为，在你新增部门的时候别人也可能会新增部门，
            // 我们必须保证在离开焦点时获取到的是所有最新部门数据
            const results = await getDepartments()
            let children = []
            if(this.title === '新增部门') {
                // 新增条件下的筛选
                children = results.filter(item => item.pid === this.department.id)
            } else {
                // 编辑条件下的筛选
                children = results.filter(item => item.pid === this.department.pid && item.id !== this.department.id)
            }
            const isRepeat = children.some(item => item.name === value)
            // isRepeat 为true，表明有重复
            if(isRepeat) {
                callback(new Error(`同级部门下已存在${value}`))
            } else {
                callback()
            }
        }
        // 校验组织架构下编码是否重复
        const checkCodeRepeat = async (rule, value, callback) => {
            const results = await getDepartments()
            let isRepeat = false
            if(this.title === '新增部门') {
                // 新增条件下的筛选
                isRepeat = results.some(item => item.code === value)
            } else {
                // 编辑条件下的筛选
                isRepeat = results.some(item => item.code === value && item.id !== this.department.id)
            }
            // isRepeat 为true，表明有重复
            if(isRepeat) {
                callback(new Error(`组织架构下已存在${value}`))
            } else {
                callback()
            }
        }
        return {
            form: {
                name: '',
                code: '',
                managerId: '',
                introduce: ''
            },
            rules: {
                name: [
                    {required: true, message: '请输入部门名称', trigger: 'blur'},
                    {min: 1, max: 20, message: '长度在1-20个字符', trigger: 'blur'},
                    { validator: checkNameRepeat, trigger: 'blur' }
                ],
                code: [
                    {required: true, message: '请输入部门编码', trigger: 'blur'},
                    {min: 1, max: 20, message: '长度在1-20个字符', trigger: 'blur'},
                    { validator: checkCodeRepeat, trigger: 'blur' }
                ],
                managerId: [
                    {required: true, message: '请选择部门负责人', trigger: 'change'}
                ],
                introduce: [
                    {required: true, message: '请输入部门介绍', trigger: 'blur'}
                ],
            },
            managerList: [] //部门负责人列表
        }
    },
    methods: {
        // 获取部门负责人列表
        async getManagerList() {
            this.managerList = await getEmployeesSimp()
        },
        // 确定提交（新增或编辑操作）
        confirmClick() {
            this.$refs['form'].validate(async (valid) => {
                if(valid) {
                    // 校验通过
                    if(this.title === '新增部门') {
                        // 新增部门操作
                        await addDepartment({...this.form, pid: this.department.id})
                        this.$message.success('新增部门成功')
                    } else {
                        // 编辑部门操作
                        await updDepartment(this.department.id, this.form)
                        this.$message.success('编辑部门成功')
                    }
                    this.$emit('confirmClick')
                } else {
                    // 校验失败
                    console.log('校验未通过');
                    return false;
                }
            })
        },
        // 取消操作
        cancelClick() {
            // 因为我们有编辑操作，需要手动将this.form恢复为原始状态，光靠this.$refs['form'].resetFields()是不行的
            // this.$refs['form'].resetFields()并不是清空表单数据，而是对整个表单进行重置，将所有字段值重置为初始值，并移除校验结果

            // 假如没有手动将this.form恢复为原始状态，在编辑状态下，然后关闭弹层，去vue调试里看，
            // 会发现form数据并没有清空（仍为回显的内容，因为form初始值在父组件里this.$refs.addDept.form = department已经被赋值了，并不为空）
            this.form = {
                name: '',
                code: '',
                managerId: '',
                introduce: ''
            }
            this.$refs['form'].resetFields()
            // 关闭弹层
            this.$emit('update:dialogVisible', false)
        }
    }
}
</script>

<style></style>